/***
 * 
 * 常规用法：
new Online({
    online: () => {
        //网络恢复正常要做的事情
    },
    lowline: () => {
        //弱网络要做的事情
    },
    offline: () => {
        //网络异常要做的事情
    },
})
* 
* 其他参数见配置defaultConfig
* **** */

const Online = function (config) {
  
  this.defaultConfig = {
    //网络正常执行函数
    online: function () {},
    //弱网执行函数
    lowline: function () {},
    //网络异常执行函数
    offline: function () {},
    //睡眠执行函数
    onsleep: function () {},
    //最小睡眠时间段(ms)
    sleepTime: 10000,
    //网络状态检测间隔时间(ms)
    lineTime: 10000,
    //检测睡眠定时器时间(ms)
    sleepInterval: 3000,
    //估算，弱网的往返时间阀值(单位：ms)
    rtt: 400,
    //网络下行速度，弱网网速阀值（MB/s）
    downlink: 1
  }
  this.onLineInfoTimeout = null;
  this.config = Object.assign(this.defaultConfig, config || {});
  this.onLineChange();
}
  
Online.prototype.onLineChange = function () {

  //针对离线应用的缓存，再次打开时的首次检测。
  if (!navigator.onLine) this.config.offline();
  //有网的情况下，进行一次弱网检测。
  else if(navigator.connection) this.onLineInfo();

  window.addEventListener("online", () => {

    this.config.online();

    if (navigator.connection) {
      clearTimeout(this.onLineInfoTimeout);
      this.onLineInfoTimeout = null;
      this.onLineInfoTimeout = setInterval(() => {
        this.onLineInfo();
      }, this.config.lineTime);
    }
    else {
      console.warn('网络监测：当前浏览器暂不支持网络状态的监测.')
    }
    
  }, false);

  window.addEventListener("offline", () => {

    this.config.offline();

    clearTimeout(this.onLineInfoTimeout);
    this.onLineInfoTimeout = null

  }, false);

  //设备睡眠监测
  this.onSleep();

}

Online.prototype.onLineInfo = function () {

  const { rtt, downlink } = navigator.connection;

  if (rtt > this.config.rrt || downlink < this.config.downlink) {
    this.config.lowline();
  }
  
}

Online.prototype.onSleep = function () {
  let time = new Date().getTime();
  setInterval(() => {
    let _t = new Date().getTime();
    if (_t - time > this.config.sleepTime) {
      this.config.onsleep();
      this.config.offline();
      if (navigator.onLine) {
        this.config.online();
        time = _t;
      }
    } else {
      time = _t;
    }
  }, this.config.sleepInterval)
}

module.exports = Online
  
